﻿using Datos.Interfaces;
using Entidad;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Dapper;
using DapperExtensions;
using System.Data;

namespace Datos.Repositories
{
    public class ProductoRepository : IProductoRepository
    {
        private readonly Microsoft.Practices.EnterpriseLibrary.Data.Database _db;

        static ProductoRepository()
        {
            //DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(), false);
        }

        public ProductoRepository()
        {
            _db = DatabaseFactory.CreateDatabase("RealConnection");
        }
        public IList<Producto> FindAll()
        {
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"SELECT * FROM Producto p
                                        JOIN Categoria c ON c.Id = p.IdCategoria
                                        JOIN Proveedor pr ON pr.Id = p.IdProveedor
                                        JOIN Marca m ON m.Id = p.IdMarca
                                        JOIN Estado e ON e.Id = p.IdEstado";

                var datos = conn.Query<Producto, Categoria, Proveedor, Marca, Estado, Producto>(query, 
                    (prod, categoria, proveedor, marca, estado) => {

                        prod.Categoria = categoria;
                        prod.Proveedor = proveedor;
                        prod.Marca = marca;
                        prod.Estado = estado;

                        return prod;
                });

                return datos.ToList();
            }
        }

        public IQueryable<Producto> Find(Expression<Func<Producto, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public Producto FindById(int id)
        {
            Producto producto;
            using (IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"SELECT * FROM Producto p
                                        JOIN Categoria c ON c.Id = p.IdCategoria
                                        JOIN Proveedor pr ON pr.Id = p.IdProveedor
                                        JOIN Marca m ON m.Id = p.IdMarca
                                        JOIN Estado e ON e.Id = p.IdEstado
                                        WHERE p.Id = @id";

                producto = conn.Query<Producto, Categoria, Proveedor, Marca, Estado, Producto>(query,
                    (prod, categoria, proveedor, marca, estado) =>
                    {

                        prod.Categoria = categoria;
                        prod.Proveedor = proveedor;
                        prod.Marca = marca;
                        prod.Estado = estado;

                        return prod;
                    }, new { id = id}).SingleOrDefault();
            }

            return producto;
        }

        public int Add(Producto newEntity)
        {
            using (IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"INSERT INTO Producto (Denominacion, IdCategoria, IdProveedor,
                                        IdMarca, Descripcion, FechaRegistro, Costo, MargenVenta, Iva,
                                        IdEstado) VALUES (@denominacion, @idcategoria, @idproveedor,
                                        @idmarca, @descripcion, @fecharegistro, @costo, @margenventa,
                                        @iva, @idestado)";

                return conn.Execute(query, new
                {
                    newEntity.Denominacion,
                    idcategoria = newEntity.Categoria.Id,
                    idproveedor = newEntity.Proveedor.Id,
                    idmarca = newEntity.Marca.Id,
                    newEntity.Descripcion,
                    fecharegistro = DateTime.Today.Date,
                    newEntity.Costo,
                    newEntity.MargenVenta,
                    newEntity.Iva,
                    idestado = newEntity.Estado.Id,

                });
            }
           
        }

        public bool Remove(int id)
        {
            bool resultado = false;
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"UPDATE Producto SET IdEstado = 2
                                        WHERE Id = @id";

                int filasAfectadas = conn.Execute(query, new
                {
                    id = id,
                });

                if (filasAfectadas > 0)
                    resultado = true;

            }

            return resultado;
        }

        public int Modify(Producto entity)
        {
            using(IDbConnection conn = _db.CreateConnection())
            {
                const string query = @"UPDATE Producto SET Denominacion = @denominacion,
                                IdCategoria = @idcategoria, IdProveedor = @idproveedor,
                                IdMarca = @idmarca, Descripcion = @descripcion, FechaRegistro = @fecharegistro,
                                Costo = @costo, MargenVenta = @margenventa, Iva = @iva, IdEstado = @idestado
                                WHERE Id = @id";

                return conn.Execute(query, new
                {
                    denominacion = entity.Denominacion, idcategoria = entity.Categoria.Id,
                    idproveedor = entity.Proveedor.Id, idmarca = entity.Marca.Id,
                    descripcion = entity.Descripcion, fecharegistro = entity.FechaRegistro,
                    costo = entity.Costo, margenventa = entity.MargenVenta, iva = entity.Iva,
                    idestado = entity.Estado.Id, id = entity.Id,
                });

            }
        }
    }
}
